<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Symbol</title>
</head>
<body>
  <!--
    前言：ES5中对象的属性名都是字符串，容易造成重名，污染环境
    Symbol：
      概念：ES6中的添加了一种原始数据类型symbol(已有的原始数据类型：String, Number, boolean, null, undefined, 对象)
      特点：
        1、Symbol属性对应的值是唯一的，解决命名冲突问题
        2、Symbol值不能与其他数据进行计算，包括同字符串拼串
        3、for in, for of遍历时不会遍历symbol属性。
      使用：
        1、调用Symbol函数得到symbol值
          let symbol = Symbol();
          let obj = {};
          obj[symbol] = 'hello';
        2、传参标识
          let symbol = Symbol('one');
          let symbol2 = Symbol('two');
          console.log(symbol);// Symbol('one')
          console.log(symbol2);// Symbol('two')
        3、内置Symbol值
          * 除了定义自己使用的Symbol值以外，ES6还提供了11个内置的Symbol值，指向语言内部使用的方法。
          - Symbol.iterator
           * 对象的Symbol.iterator属性，指向该对象的默认遍历器方法(后边讲)
  -->


<script type="text/javascript">
	
		const s1=Symbol('onw');
		const s2=Symbol('two');
		console.log(s1,s2,s1===s2);//Symbol(onw) Symbol(two) false
 
		const a=Symbol();
		// 将Symbol()类型的数据当做属性名去用,独一无二无法改变
		let obj={
			[a]:1,
			b:2,
			c:3
		}	 
		//添加了一个属性a,原来设置的Symbol属性a没有改变
		obj.a=4;
		console.log(obj);//{b: 2, c: 3, a: 4, Symbol(): 1}
		
		for(s in obj){
			console.log(obj[s]);//不会遍历symbol属性 2 3 4
		}
		
		// 因为是唯一的值,所以不会重复,即属性相同就覆盖前面的
		const classRoom={
			[Symbol('Lily')]:{grade:60,gender:'famale'},
			[Symbol('Nina')]:{grade:80,gender:'famale'},
			[Symbol('Nina')]:{grade:90,gender:'mall'},
		}
		console.log(classRoom);//{Symbol(Lily): {…}, Symbol(Nina): {…}, Symbol(Nina): {…}}
		
		// 遍历Symbol数据类型 
		var syms=Object.getOwnPropertySymbols(classRoom).map(
			sym=>classRoom[sym]
		)
		console.log(syms);
		/*
			0: {grade: 60, gender: "famale"}
			1: {grade: 80, gender: "famale"}
			2: {grade: 90, gender: "mall"}
		*/
    
</script>

</body>
</html>